package org.gulugulubiao.aspect;

import org.gulugulubiao.annoctation.AutoCreateId;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;

import org.gulugulubiao.enumeration.EntityType;
import org.gulugulubiao.utils.RedisIdUtil;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@Aspect
@RequiredArgsConstructor
public class AutoCreateIdAspect {
    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 切入点
     */
    @Pointcut("execution(* org.gulugulubiao.mapper.*.*(..)) && @annotation(org.gulugulubiao.annoctation.AutoCreateId)")
    public void autoCreateIdPointCut() {
    }

    /**
     * 前置通知，在通知中进行公共字段的赋值
     */
    @Before("autoCreateIdPointCut()")
    public void autoFill(JoinPoint joinPoint) {
        log.info("开始进行Id自动生成...");
        //Signature signature1 = joinPoint.getSignature();
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //MethodSignature是Signature的一个子接口，专门用于表示方法签名。
        //它提供了额外的方法，可以获取方法的参数类型、返回值类型等信息。这在处理方法增强时非常有用。
        AutoCreateId annotation = signature.getMethod().getAnnotation(AutoCreateId.class);// 返回注解对象
        EntityType value = annotation.value();

        // 获取被拦截的参数
        Object[] args = joinPoint.getArgs(); //规定插入数据库方法的第一个参数为插入实体

        if (args == null || args.length == 0) {
            return;
        }

        Object entity = args[0];

        String keyPrefix = value.toString();

        // 构造Id
        long id = RedisIdUtil.nextId(keyPrefix, stringRedisTemplate);

        // 插入生成的id
        try {
            entity.getClass().getDeclaredMethod("setId", Long.class).invoke(entity, id);
        } catch (Exception e) {
            log.error("生成Id失败");
            e.printStackTrace();
        }

    }
}
